#pragma once

#include "pch.h"
#include "Clazz.h"
#include "Method.h"
#include "Object.h"
#include "Assembly.h"

namespace mono
{
    struct Domain
    {

        struct Desc
        {
            std::string m_LibPath, m_ConfigPath, m_DebugName;
            //Desc() : m_LibPath("/usr/lib"), m_ConfigPath("/etc/mono/config")
            Desc() : m_LibPath("C:/Program Files/Mono/lib"), m_ConfigPath("/etc/mono/config")
            {
            }
        } m_Desc;

        MonoDomain *m_Domain;

        Domain(const Desc &desc)
            : m_Desc(desc)
        {
            mono_set_dirs(m_Desc.m_LibPath.c_str(), m_Desc.m_ConfigPath.c_str());
            m_Domain = mono_jit_init(m_Desc.m_DebugName.c_str());
        };

        std::shared_ptr<Assembly> OpenAssembly(const std::string &path)
        {
            return std::make_shared<Assembly>(mono_domain_assembly_open(m_Domain, path.c_str()));
        };

        std::shared_ptr<Object> NewInstance(Clazz clazz)
        {
            return std::make_shared<Object>(mono_object_new(m_Domain, clazz.m_Class));
        };
        static std::shared_ptr<Object> NewInstanceDomain(Clazz clazz)
        {
            return std::make_shared<Object>(mono_object_new(mono_domain_get(), clazz.m_Class));
        };
        void Cleanup()
        {
            mono_jit_cleanup(m_Domain);
        }
        ~Domain()
        {
            Cleanup();
        }
    };
};